/**
 * This class creates a live list of the Charts available from the Telemetry Analysis service.
 */
package org.hackystat.ui.telemetryviewer.client;

import java.util.ArrayList;
import java.util.Iterator;

import org.hackystat.ui.telemetryviewer.client.common.BasicConveyor;
import org.hackystat.ui.telemetryviewer.client.common.Session;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * This class creates a live list of the Charts available from the Telemetry Analysis service.
 * @author David J. Nickles
 *
 */
public class ChartSelectionPanel extends VerticalPanel implements ChangeListener, 
  WindowResizeListener {

  private CompositeChartPanel compositeChart;
  private Image statusImage;
  private Label header;
  private ListBox chartServicesListBox;
  private Session session;

  /**
   * Create a live list of the Charts available from the Telemetry Analysis service.
   * 
   * @param session the current session attributes
   */
  public ChartSelectionPanel(Session session) {
    this.session = session;
    
    setStyleName(Styles.TOPPANEL);
    HorizontalPanel hp = new HorizontalPanel();
    hp.add(this.header = new Label("Telemetry Chart Services"));
    this.header.setStyleName(Styles.SMALLLABEL);
    hp.setCellHorizontalAlignment(this.header, HasHorizontalAlignment.ALIGN_LEFT);
    hp.add(this.statusImage = new Image(Images.WAIT_IMAGE));
    hp.setCellHorizontalAlignment(this.statusImage, HasHorizontalAlignment.ALIGN_LEFT);
    this.statusImage.setSize(Styles.SMIMAGESIZE, Styles.SMIMAGESIZE);
    this.statusImage.setVisible(false);
    hp.add(this.chartServicesListBox = new ListBox());
    hp.setCellHorizontalAlignment(this.chartServicesListBox, HasHorizontalAlignment.ALIGN_LEFT);
    this.chartServicesListBox.addChangeListener(this);
    add(hp);

    Window.addWindowResizeListener(this);
    setWidth(Integer.toString(Window.getClientWidth() - 42) + Styles.PIXELSUFFIX);
  }

  
  /**
   * This method displays the chart selector panel in the UI.
   */
  public void init() {
    RootPanel.get(CompositeWidget.CHART_SELECT_ELEMENT_ID).clear();
    RootPanel.get(CompositeWidget.CHART_SELECT_ELEMENT_ID).add(this);
    rpcGetCharts();
  }
  
  /**
   * This method processes the get chart index result.
   * @param conveyor carrying the chart names and descriptions.
   */
  private void setCharts(BasicConveyor conveyor) {
    this.statusImage.setVisible(false);
    if (Boolean.TRUE.toString().equals(conveyor.getStatus())) {
      ArrayList charts = conveyor.getLists();
      if (charts.isEmpty()) {
        this.header.setText("No telemetry chart services available.");
        this.header.setStyleName(Styles.INVALIDLABEL);
      }
      else {
        Iterator it = charts.iterator();
        while (it.hasNext()) {
          ArrayList info = (ArrayList)it.next();
          String name = (String)info.get(0);
          String description = (String)info.get(1);
          this.chartServicesListBox.addItem(name, description);
        }
        this.header.setText("Please select from the following available telemetry charts:");
        this.compositeChart = new CompositeChartPanel(this.session, 
          this.chartServicesListBox.getItemText(this.chartServicesListBox.getSelectedIndex()),
          this.chartServicesListBox.getValue(this.chartServicesListBox.getSelectedIndex()));
        this.compositeChart.init();
      }
    }
    else {
      CompositeWidget.showAlert(conveyor.getStatus());
    }
  }
  
  /**
   * Check with the servlet to get the host name from the properties file.
   */
  private void rpcGetCharts() {
    this.statusImage.setVisible(true);
    this.header.setText("Requesting available telemetry charts.");
    RPCServiceFactory.getInstance().getService().getCharts(this.session, new AsyncCallback()
      {
        public void onSuccess(Object result) {
          setCharts((BasicConveyor) result);
        }
    
        public void onFailure(Throwable caught) {
          if (caught instanceof com.google.gwt.user.client.rpc.InvocationException) {
            CompositeWidget.log(RPCServiceFactory.PRCERRORNAME, 
              "Cannot invoke get-charts on servlet.");
          } 
          else {
            CompositeWidget.log(RPCServiceFactory.PRCERRORNAME, caught.toString());
          }
        }
      });
  }

  /**
   * This method repsonds to the listbox changes.
   * @param sender the widget that was changed.
   */
  public void onChange(Widget sender) {
    
    this.compositeChart = new CompositeChartPanel(this.session, 
      this.chartServicesListBox.getItemText(this.chartServicesListBox.getSelectedIndex()),
      this.chartServicesListBox.getValue(this.chartServicesListBox.getSelectedIndex()));
    this.compositeChart.init();
  }

  /** 
   * Listens for user resizing of the window.
   * @param width of the adjusted window..
   * @param height of the adjusted window.
   */
  public void onWindowResized(int width, int height) {
    setWidth(Integer.toString(width - Styles.RIGHTOFFSET) + Styles.PIXELSUFFIX);
  }
}
